﻿using IM.Easy.Core.Extensions;
using IM.Easy.Core.Services;
using IM.Easy.Core.Utils;
using IM.Easy.Entity.System;
using IM.Easy.Infrastructure.Query;
using IM.Easy.SystemServices.Dtos;
using IM.Easy.SystemServices.IServices;
using Mapster;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IM.Easy.SystemServices.Services
{
    public class DictDataService(ISqlSugarClient db) : AppServices<SysDictData>(db), IDictDataService
    {
        private const string cachePrefix = "data_type_key";

        /// <summary>
        /// 获取字典数据详细数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public DictDataDto GetData(long id)
        {
            var instance = Db.Queryable<SysDictData>()
                            .Where(s => s.Id == id)
                            .First();
            return instance.Adapt<DictDataDto>();
        }

        /// <summary>
        /// 根据字典类型获取数据
        /// </summary>
        /// <param name="types"></param>
        /// <returns></returns>
        public List<DictDataDto> GetByTypes(params string[] types)
        {
            var cacheKey = $"{cachePrefix}_GetByTypes_{types}";
            var list = db.Queryable<SysDictData>()
                        .LeftJoin<SysDictType>((d, t) => d.Group == t.Code)
                        .Where(d => types.Contains(d.Group))
                        .Select((d, t) => new DictDataDto
                        {
                            DataType = t.DataType,
                        }, true)
                        //.WithCache(cacheKey).ToList();
                        .ToList();
            return list.Adapt<List<DictDataDto>>();
        }

        /// <summary>
        /// 添加字典数据
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public long Add(DictDataDto dto)
        {
            var model = dto.Adapt<SysDictData>();
            ValidateUnique(dto);
            //ClearCache();
            return Db.Insertable(model).ExecuteReturnSnowflakeId();
        }

        /// <summary>
        /// 更新字典数据
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public bool Update(DictDataDto dto)
        {
            var model = dto.Adapt<SysDictData>();
            ValidateUnique(dto);
            //ClearCache();
            var hasChange = Db.Updateable(model).ExecuteCommandHasChange();
            return hasChange;
        }

        /// <summary>
        /// 校验唯一性
        /// </summary>
        /// <param name="dto"></param>
        private void ValidateUnique(DictDataDto dto)
        {
            var duplicate = Db.Queryable<SysDictData>().Any(s => dto.Id != s.Id && dto.Value == s.Value && dto.Group == s.Group);
            if (duplicate) ExceptionUtils.ThrowBusinessException($"字典数据{dto.Value}重复");
        }

        /// <summary>
        /// 获取数据列表
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public PageResponse<DictDataDto> GetList(DictDataQueryDto query)
        {
            var exp = Expressionable.Create<SysDictData>()
                .AndIF(!string.IsNullOrEmpty(query.Group), s => s.Group == query.Group)
                .AndIF(!string.IsNullOrEmpty(query.Label), s => s.Label.Contains(query.Label))
                .ToExpression();

            var list = db.Queryable<SysDictData>();
            list = list.Where(exp);

            var page = list.ToPageListAsync<SysDictData, DictDataDto>(query);
            return page;
        }
    }
}
